#ifndef __AVOS_POOL_H_
#define __AVOS_POOL_H_

#include <avos/list.h>

struct pool_item {
	list_t list;
};

typedef struct {
	list_t head;
} pool_t;

/**
 * Initialize memory pool
 */
static inline void pool_init(pool_t *p, void *mem, size_t size, size_t itemsize)
{
	int i;
	int num_items = size / itemsize;
	struct pool_item *ptr;

	/* Item size should be large enough to hold pool item */
	if (itemsize < sizeof(struct pool_item))
		itemsize = sizeof(struct pool_item);

	list_init(&p->head);

	ptr = (struct pool_item *) mem;

	/* create a list of free chunks (pool list) */
	for (i = 0; i<num_items; i++) {
		list_add_tail(&p->head, &ptr->list);
		ptr = (void *)ptr + itemsize;
	}
}

/**
 * Allocate a single item from pool
 */
static inline void *pool_alloc(pool_t *p)
{
	struct pool_item *item;
	/* Return NULL if pool has no items available */
	if (list_empty(&p->head))
		return NULL;

	/* Get the first item, delete it from the pool list and return it. */
	item = list_first(&p->head, struct pool_item, list);
	list_del(&item->list);

	return ((void *) item);
}

/**
 * Free item and put it pack to pool
 */
static inline void pool_free(pool_t *p, void *mem)
{
	struct pool_item *item;

	if (mem == NULL)
		return;

	/* Add item to the pool list so it can be reused */
	item = mem;

	list_add_tail(&p->head, &item->list);
}

#endif /* __POOL_H_ */
